package com.example.test1.service.Impl;

import com.example.test1.Dto.WordDetailsDTO;
import com.example.test1.Dto.WordOpDTO;
import com.example.test1.Dto.WordProficiencyDTO;
import com.example.test1.service.WordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;


@Service
public class WordServiceImpl implements WordService {

    @Autowired
    StringRedisTemplate stringRedisTemplate = null;

    /**
     * 收藏单词
     *
     * @param wordOpDto
     */

    @Override
    public void collect(WordOpDTO wordOpDto) {
        String openId = wordOpDto.getOpenId();
        String word = wordOpDto.getWordContent();
        //openId + "List"表示的是编号为openId的用户到其收藏的单词的映射
        BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(openId + "List");
        listOps.rightPush(word);
        //openId + "Hash"表示的是编号为openId的用户的所有收藏单词到熟练度的映射
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(openId + "Hash");
        hashOps.put(word, "0.0");
    }

    /**
     * 从收藏列表中删除指定单词
     *
     * @param wordOpDto
     */

    @Override
    public void delete(WordOpDTO wordOpDto) {
        String openId = wordOpDto.getOpenId();
        String word = wordOpDto.getWordContent();
        BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(openId + "List");
        listOps.remove(1, word);
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(openId + "Hash");
        hashOps.delete(word);
    }

    /**
     * 搜寻单词！！！
     *
     * @param wordOpDto
     * @return 单词详细
     */

    @Override
    public WordDetailsDTO search(WordOpDTO wordOpDto) {
        String openId = wordOpDto.getOpenId();
        String word = wordOpDto.getWordContent();
        return getWordDetails(word, getWordProficiency(openId, word));
    }

    /**
     * 获得随机5个单词
     *
     * @param openId
     * @return 单词列表
     */

    @Override
    public List<WordDetailsDTO> randomWord(String openId) {
        BoundSetOperations<String, String> setOps = stringRedisTemplate.boundSetOps("words");
        List<WordDetailsDTO> ret = new ArrayList<>();
        Set<String> words = setOps.distinctRandomMembers(5);
        for (String word : words) {
            ret.add(getWordDetails(word, getWordProficiency(openId, word)));
        }
        return ret;
    }

    /**
     * 根据用户id获取其收藏的所有单词
     *
     * @param openId
     * @return
     */
    @Override
    public Map<Long, WordDetailsDTO> getCollectedWords(String openId) {
        BoundListOperations<String, String> listOps = stringRedisTemplate.boundListOps(openId + "List");
        Map<Long, WordDetailsDTO> ret = new HashMap<>();
        long size = listOps.size();
        for (long idx = 0; idx < size; idx++) {
            String word = listOps.index(idx);
            ret.put(idx, getWordDetails(word, getWordProficiency(openId, word)));
        }
        return ret;
    }

    /**
     * 设置用户对单词的熟练度
     *
     * @param wordProficiencyDto
     */

    @Override
    public void setWordProficiency(WordProficiencyDTO wordProficiencyDto) {
        String openId = wordProficiencyDto.getOpenId();
        String word = wordProficiencyDto.getWordContent();
        String proficiency = wordProficiencyDto.getProficiency() + "";
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(openId + "Hash");
        hashOps.put(word, proficiency);
    }

    /**
     * 初始化关于单词的redis数据库
     */

    /**
     * 获取单词的详细内容，包括读音、意思以及用户对其熟练度。
     *
     * @param word        单词文本内容
     * @param proficiency 单词优先级
     * @return WordDetails单词的详细内容
     */
    private WordDetailsDTO getWordDetails(String word, double proficiency) {
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(word);
        String pronunciation = hashOps.get("pronunciation");
        String meanings = hashOps.get("meaning");
        Set<String> set = new HashSet<>();
        //按照*进行拆分
        for (String meaning : meanings.split("\\*")) {
            set.add(meaning);
        }
        WordDetailsDTO wordDetails = WordDetailsDTO.builder().wordContent(word)
                .pronunciation(pronunciation)
                .meaning(set)
                .proficiency(proficiency)
                .build();
        return wordDetails;
    }

    /**
     * 获取用户对单词的熟练度
     *
     * @param openId
     * @param word
     * @return
     */


    private double getWordProficiency(String openId, String word) {
        BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(openId + "Hash");
        String proficiency = hashOps.get(word);
        if (proficiency == null) {
            return 0.0;
        } else {
            return Double.parseDouble(hashOps.get(word));
        }
    }


    @Override
    public void initWords() {
        String docDir = System.getProperty("user.dir") + "/text";
        String wordDir = docDir + "/word.txt";
        String pronunciationDir = docDir + "/accent.txt";
        String meaningDir = docDir + "/mean.txt";
        File words = new File(wordDir);
        File pronunciations = new File(pronunciationDir);
        File meanings = new File(meaningDir);
        String word = null;
        String pronunciation = null;
        String meaning = null;
        try {
            BufferedReader wr = new BufferedReader(new InputStreamReader(new FileInputStream(words)));
            BufferedReader pr = new BufferedReader(new InputStreamReader(new FileInputStream(pronunciations)));
            BufferedReader mr = new BufferedReader(new InputStreamReader(new FileInputStream(meanings)));
            word = wr.readLine();
            pronunciation = pr.readLine();
            meaning = mr.readLine();
            while (word != null) {
                Map<String, String> map = new HashMap<>();
                map.put("pronunciation", pronunciation);
                map.put("meaning", meaning);
                //创建单词文本到其读音等详细内容的映射
                stringRedisTemplate.opsForHash().putAll(word, map);
                //创建单词表到单词的映射words
                stringRedisTemplate.opsForSet().add("words", word);
                word = wr.readLine();
                pronunciation = pr.readLine();
                meaning = mr.readLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(word);
        }
    }

}
